from datetime import datetime
from urllib.parse import quote_plus

from sqlalchemy import BigInteger, Column, DateTime, String
from sqlalchemy.ext.asyncio import AsyncAttrs, async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBase
from utils.snowflake import SnowflakeGenerator

from config.env import DataBaseConfig

ASYNC_SQLALCHEMY_DATABASE_URL = (
    f'mysql+asyncmy://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@'
    f'{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}'
)
if DataBaseConfig.db_type == 'postgresql':
    ASYNC_SQLALCHEMY_DATABASE_URL = (
        f'postgresql+asyncpg://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@'
        f'{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}'
    )

# mssql+aioodbc://<username>:<password>@<dsnname>
if DataBaseConfig.db_type == 'mssql':
    ASYNC_SQLALCHEMY_DATABASE_URL = (
        f'mssql+aioodbc://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@'
        f'{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}?driver=ODBC+Driver+17+for+SQL+Server&TrustServerCertificate=yes'
    )

async_engine = create_async_engine(
    ASYNC_SQLALCHEMY_DATABASE_URL,
    echo=DataBaseConfig.db_echo,
    max_overflow=DataBaseConfig.db_max_overflow,
    pool_size=DataBaseConfig.db_pool_size,
    pool_recycle=DataBaseConfig.db_pool_recycle,
    pool_timeout=DataBaseConfig.db_pool_timeout,
)
AsyncSessionLocal = async_sessionmaker(autocommit=False, autoflush=False, bind=async_engine)


print('数据库配置')
print(ASYNC_SQLALCHEMY_DATABASE_URL)


class Base(AsyncAttrs, DeclarativeBase):
    pass


# 抽象基类 (不会创建数据库表)
class BaseEntity(Base):
    __abstract__ = True  # 关键声明

    # def to_json(self):
    #     dict = self.__dict__
    #     if '_sa_instance_state' in dict:
    #         del dict['_sa_instance_state']
    #     return dict

    def gen_id():
        gen = SnowflakeGenerator(42)
        return next(gen)

    # id = db.Column(db.String(32),default=gen_id,primary_key=True)
    # 公共字段定义 (所有子类都会继承)
    id = Column(BigInteger, primary_key=True, default=gen_id, comment='主键')
    del_flag = Column(String(1), default='0', comment='删除标志（0代表存在 2代表删除）')
    create_by = Column(String(64), nullable=True, default='', comment='创建者')
    create_at = Column(DateTime, nullable=False, default=datetime.now(), comment='创建时间')
    update_by = Column(String(64), default='', comment='更新者')
    update_at = Column(DateTime, onupdate=datetime.now(), comment='更新时间')
